import azure.cognitiveservices.speech as speechsdk
import subprocess
import io

"""
语音识别方案： ffmpeg + azure
安卓端上传来的文件是m4a文件，azure不支持，需要转为wav, 先调用m4a_to_wav_in_memory， 再调用speech_to_text
"""


async def m4a_to_wav_in_memory(m4a_data):
    # 将 m4a 数据写入内存中的临时文件
    input_buffer = io.BytesIO(m4a_data)
    output_buffer = io.BytesIO()

    # 使用 ffmpeg 将 m4a 转换为 wav
    process = subprocess.Popen(
        ['ffmpeg', '-i', 'pipe:0', '-f', 'wav', 'pipe:1'],
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE
    )

    wav_data, _ = process.communicate(input_buffer.read())
    output_buffer.write(wav_data)
    output_buffer.seek(0)

    return output_buffer.read()


async def speech_to_text(audio_file_bytes, region="eastus", subscription_key="4901319c9334473dbde4c68e7eaa51d7"):
    audio_file_bytes = await m4a_to_wav_in_memory(audio_file_bytes)
    # 初始化语音配置
    speech_config = speechsdk.SpeechConfig(subscription=subscription_key, region=region)
    speech_config.speech_recognition_language = "zh-CN"

    # 创建一个 MemoryStream 对象，并将文件内容写入其中
    audio_stream = speechsdk.audio.PushAudioInputStream()
    audio_config = speechsdk.audio.AudioConfig(stream=audio_stream)

    # 将音频文件的内容读取到内存中
    audio_file = io.BytesIO(audio_file_bytes)
    audio_file.seek(0)
    audio_data = audio_file.read()
    audio_stream.write(audio_data)
    audio_stream.close()

    # 创建一个语音识别器
    speech_recognizer = speechsdk.SpeechRecognizer(speech_config=speech_config, audio_config=audio_config)

    # 开始识别（同步）
    # print("开始语音识别...")
    result = speech_recognizer.recognize_once()
    print(result.text)

    # 返回结果
    if result.reason == speechsdk.ResultReason.RecognizedSpeech:
        return {"status": "success", "text": result.text}
    elif result.reason == speechsdk.ResultReason.NoMatch:
        return {"status": "nomatch", "text": "没有匹配的语音结果。"}
    elif result.reason == speechsdk.ResultReason.Canceled:
        cancellation_details = result.cancellation_details
        return {"status": "canceled",
                "text": f"语音识别被取消: {cancellation_details.reason}, {cancellation_details.error_details}"}
    else:
        return {"status": "error", "text": "未知错误。"}


if __name__ == "__main__":
    # 假设 audio_file 是一个文件对象，例如通过 open() 打开的文件
    with open("./output.m4a", "rb") as audio_file:
        result = speech_to_text(audio_file.read())
    print(f"状态: {result['status']}, 识别出的文本: {result['text']}")
